package com.sumainfor.pc.gmio.service.impl;

import com.qiniu.util.Json;
import com.qiniu.util.StringUtils;
import com.sumainfor.common.Constants;
import com.sumainfor.common.config.RedisUtils;
import com.sumainfor.common.entity.TemplateData;
import com.sumainfor.common.util.*;
import com.sumainfor.common.utlis.*;
import com.sumainfor.common.wechat.WeChatConfig;
import com.sumainfor.pc.gmio.dao.MktFeign.MarketPactMapper;
import com.sumainfor.pc.gmio.dao.SeBillPayMapper;
import com.sumainfor.pc.gmio.dao.SeTemporaryMapper;
import com.sumainfor.pc.gmio.dao.SeTenantBillMapper;
import com.sumainfor.pc.gmio.dao.UtilsMapper;
import com.sumainfor.pc.gmio.feign.CfoFeign.CfoFeign;
import com.sumainfor.pc.gmio.feign.Zfeign.ZpcEpcFeign;
import com.sumainfor.pc.gmio.feign.Zfeign.ZpcMktFeign;
import com.sumainfor.pc.gmio.feign.Zfeign.ZzuulFeign;
import com.sumainfor.pc.gmio.service.SeTenantBillService;
import net.sf.json.JSONObject;
import org.apache.commons.collections.MapUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 账单
 */
@Service
public class SeTenantBillSerivceImpl implements SeTenantBillService {

    private ReentrantLock lock = new ReentrantLock(false);
    Logger log = LoggerFactory.getLogger(SeTenantBillSerivceImpl.class);
    @Autowired
    private SeTenantBillMapper seTenantBillMapper;
    @Autowired
    private SeTemporaryMapper seTemporaryMapper;
    @Autowired
    private ZpcMktFeign zpcMktFeign;
    @Autowired
    private ZzuulFeign zzuulFeign;
    @Autowired
    private ZpcEpcFeign zpcEpcFeign;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private SeBillPayMapper seBillPayMapper;
    @Autowired
    CfoFeign CfoFeign;
    @Autowired
    MarketPactMapper marketPactMapper;




    @Autowired
    private UtilsMapper utilsMapper;
    String UUID = null;
    String UUID2 = null;


    /**
     * 查询账单列表
     *
     * @param params
     * @return
     */
    @Override
    public JsonResult getTenantBillList(Map<String, Object> params, Pager pager) {
        JsonResult result = new JsonResult();
        PageUtils pageUtils = new PageUtils();
        //查询运营部账单列表
        List<Map<String, Object>> list = seTenantBillMapper.getTenantBillList(params);
        //保存租客的编号和房源的编号
        //把运营部的房源编号传递到市场部
        if (list.size()>0){
            params.put("tenBillList", list);
            result=zpcMktFeign.getHouInfoListForGmioTcmkt(params);
        }else{
            result=pageUtils.getJsonResult(new ArrayList<Map<String,Object>>(), params, 0);
        }

        //查询市场部的房源详表信息
        return result;
    }

    /**
     * 查询账单总数
     *
     * @param params
     * @return
     */
    @Override
    public Integer getTenantBillListCount(Map<String, Object> params) {
        return seTenantBillMapper.getTenantBillListCount(params);
    }

    /**
     * 通过客户编号查询账单列表
     */
    @Override
    public List<Map<String, Object>> getTenantBillListByTenId(Map<String, Object> params) {
        //zc修改
        List<String> SysUserId = new ArrayList<>();
        List<Map<String,Object>> getTenantBillListByTenId = seTenantBillMapper.getTenantBillListByTenId(params);
        if (getTenantBillListByTenId.size()>0){
            for (Map zcMap:getTenantBillListByTenId) {
                if (!StringUtils.isNullOrEmpty(MapUtils.getString(zcMap,"AuditId"))){
                    SysUserId.add(MapUtils.getString(zcMap,"AuditId"));
                }
            }

            if (SysUserId.size()>0){
                Map<String,Object> mapOne = new HashMap<>();
                mapOne.put("SysUserId",SysUserId);
                JsonResult zuulResult = zzuulFeign.getLoginName(mapOne);
                List<Map<String,Object>> zuulList = (List<Map<String, Object>>) zuulResult.get("result");
                if (zuulList.size()>0){
                    for (Map map1:getTenantBillListByTenId) {
                        for (Map map2:zuulList) {
                            if (MapUtils.getString(map1,"AuditId")!=null&&MapUtils.getString(map2,"user_id")!=null&&MapUtils.getString(map1,"AuditId").equals(MapUtils.getString(map2,"user_id"))){
                                map1.putAll(map2);
                            }
                        }
                    }
                }
            }




        }
        return  getTenantBillListByTenId;

//        return seTenantBillMapper.getTenantBillListByTenId(params);
    }

    /**
     * 通过客户编号查询历史账单总数
     */
    @Override
    public Integer getTenantBillListCountByTenId(Map<String, Object> params) {
        return seTenantBillMapper.getTenantBillListCountByTenId(params);
    }

    /**
     * 查询服务水电燃账单列表
     */
    @Override
    public List<Map<String, Object>> getWegBillList(Map<String, Object> params) {
        //查询运营部水电燃的列表
        List<Map<String, Object>> wegBillList = seTenantBillMapper.getWegBillList(params);
        //b保存录入账单的服务秘书的编号
        List<String> idList = new ArrayList<String>();
        for (Map<String, Object> map : wegBillList) {
            if (map.get("Create") != null) {
                idList.add(map.get("Create").toString());
            }
        }
        params.put("idList", idList);
        JsonResult result = zzuulFeign.getWegNameList(params);
        List<Map<String, Object>> zuulList = (List<Map<String, Object>>) result.get("result");
        for (Map<String, Object> giomap : wegBillList) {
            for (Map<String, Object> zuulmap : zuulList) {
                if (MapUtils.getString(giomap, "Create").equals(MapUtils.getString(zuulmap, "user_id"))) {
                    giomap.putAll(zuulmap);
                }
            }
        }
        return wegBillList;
    }

    /**
     * 查询服务秘书水电燃账单列表总数
     */
    @Override
    public Integer getWegBillListCount(Map<String, Object> params) {
        return seTenantBillMapper.getWegBillListCount(params);
    }

    /**
     * 市场部签约合同新增
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public JsonResult addTenantBillForPact(Map<String, Object> params) {
        JsonResult result = new JsonResult();
        /**
         * 加锁操作
         */
        lock.lock();
        try {
            try {
                //组装数据
                System.out.println("市场部接收到的参数:" + params);
                String dateParam = "";//合同开始时间
                Date date = new Date();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                //获取合同周期
                if (params.get("payFu") == null || params.get("monthMoney") == null
                        || params.get("bottomADate") == null || params.get("TenId") == null || params.get("HouId") == null
                        || params.get("HouInfoId") == null || params.get("PaId") == null || params.get("Pmethod") == null
                        || params.get("payYa") == null || params.get("CorId") == null || params.get("WaDeposit") == null) {
                    return result.putFailed("参数不正确");
                }




                //根据配置标准查询房源配置
                Map<String,Object> getChaIdMap  = marketPactMapper.getChaId(params);
                if (getChaIdMap==null){
                    return  result.putFailed("配置标准异常");
                }
                //查询房源是否存在智能电表
                JsonResult MarketPayMentRe = zpcMktFeign.getHouInfoPayment(params);
                Map<String,Object> MarketPayment = (Map<String,Object>)MarketPayMentRe.get("result");
                Integer Payment = MapUtils.getInteger(MarketPayment,"Payment");//0.预付费   1.后付费\n如果房源配置有智能电表，那就是预付费

                BigDecimal WaterPricings =  new BigDecimal("0");//水费定额定价
                BigDecimal GasPricings =  new BigDecimal("0");//燃气费定额定价
                BigDecimal actualDeposit = new BigDecimal(params.get("actualDeposit").toString());//押金为固定值
                BigDecimal BroadBand = new BigDecimal(params.get("BroadBand").toString());//宽带


               if (MapUtils.getInteger(params,"ProOperaType")==1){//合租
                   if(Payment == 0){//智能电表 //水费燃气费宽带跟着付款周期一起出账单 无水电押金
                       WaterPricings = new BigDecimal(getChaIdMap.get("WaterPricings").toString());//水费固定
                       GasPricings = new BigDecimal(getChaIdMap.get("GasPricings").toString());//燃气费固定
                   }
               }





                params.put("wgnFu",params.get("payFu"));//用于生成固定金额水燃宽带的时长(暂时无用)
                int payFuOne = MapUtils.getInteger(params,"payFu")-MapUtils.getInteger(params,"SenSend");//减去送的月份
                params.put("payFu",payFuOne);//减去送的月份后的签约时长


                BigDecimal Firstmonth = new BigDecimal(params.get("Firstmonth").toString());//首月房租
                int pCount = 0;  //每次缴房租，缴几个月
                int paCount = 0;   //合同周期内需要缴几次房租
                int yaCount = Integer.parseInt(params.get("payYa").toString());   //需要押几个月
                int count = Integer.parseInt(params.get("payFu").toString());    //合同签约时长
                BigDecimal monthMoney = new BigDecimal(params.get("monthMoney").toString());//房屋月租金
                BigDecimal WaDeposit = new BigDecimal(params.get("WaDeposit").toString());//首月水电押金
                int yueCont = 0;//合同周期除以每次缴房租，缴几个月， 剩余的月份
                boolean isYue = false;//是否有余数
                //0月付  1季付  2半年付  3年付
                if (params.get("Pmethod").toString().equals("0")) {
                    pCount = 1;
                } else if (params.get("Pmethod").toString().equals("1")) {
                    pCount = 3;
                } else if (params.get("Pmethod").toString().equals("2")) {
                    pCount = 6;
                } else if (params.get("Pmethod").toString().equals("3")) {
                    pCount = 12;
                }

                //合同周期除以每次缴房租，缴几个月，计算需要缴几次房租，如果有余就加一
                if ((double) count % (double) pCount == 0) {
                    paCount = (count / pCount);
                } else {
                    paCount = (count / pCount) + 1;
                    //如果有余数才去计算最后一次缴费要缴几个月
                    yueCont = (count - (count / pCount) * pCount);//最后一次账单需要交几个月
                }
                System.out.println("每次缴房租，缴几个月pCount" + pCount);
                System.out.println("合同周期内需要缴几次房租paCount" + paCount);
                System.out.println("需要押几个月yaCount" + yaCount);
                System.out.println("合同签约时长count" + count);
                System.out.println("房屋月租金monthMoney" + monthMoney);


                //将合同周期内需要交房租次数
                params.put("paCount",paCount);
                //将每次需要交房租的月数
                params.put("pCount",pCount);
                //将最后一次账单需要交的月份
                params.put("yueCont",yueCont);
                params.put("WaterPricings",WaterPricings);
                params.put("GasPricings",GasPricings);
                params.put("BroadBand",BroadBand);




                if (paCount > 0) {
                    //合同开始时间
                    dateParam = params.get("bottomADate").toString();
                    date = DateUtils.stringToDate(dateParam, "yyyy-MM-dd");
                    //组装数据
                    Map<String, Object> map = new HashMap<String, Object>();
                    //获取账单编号
                    Map<String, Object> uuid = utilsMapper.getUUID(new HashMap<String, Object>() {{
                        put("uuid", "BiId");
                        put("database", Constants.DATA_SOURCE_GMIO);
                        put("surface", "tcgmio_tenant_bill");
                    }});
                    if (uuid != null && (!uuid.get("uuid").toString().equals(""))) {
                        int number = Integer.valueOf(uuid.get("uuid").toString());
                        UUID = ComUtils.getLocalTrmSeqNum("bi" + 0, number);
                    } else {
                        UUID = ComUtils.getLocalTrmSeqNum("bi" + 0, 0);
                    }
                   // map.put("BillExplain", "房租:" + (monthMoney.multiply(new BigDecimal(String.valueOf(pCount)))) + ",房租押金:" +(monthMoney.multiply(new BigDecimal(String.valueOf(yaCount)))));
                    map.put("BillExplain", "房租:" + (Firstmonth.add(monthMoney.multiply(new BigDecimal(String.valueOf(pCount-1))))) + ",房租押金:" +(actualDeposit.multiply(new BigDecimal(String.valueOf(yaCount)))));
                    map.put("BiId", UUID);//账单编号
                    map.put("CorId", params.get("CorId"));//房源所属的公司编号
                    map.put("BiGenerated", params.get("bottomADate"));//首月账单生成时间
                    map.put("EndTime", DateUtils.format(DateUtils.addDateMonthsToEnd(date, ((1) * pCount))));//账单结束时间
                    map.put("LateDay", map.get("BiGenerated"));//账单最晚付款日
                    map.put("by", "auto");//操作人
                    map.put("IfTemporary", 1);//是否是临时账单    0.否   1.是\n没有关联来源',
                    map.put("BiType", 1);//1.房租 2.公共事业费  3.维修费用  \n4.延期退审核  5.其他费用  6.退租账单
                    map.put("Source", params.get("PaId"));//账单来源编号根据类型 这里存的是合同的编号
                   // map.put("BiMoney", monthMoney.multiply(new BigDecimal(String.valueOf((pCount + yaCount) ))));//账单金额

                    map.put("BiMoney",Firstmonth.add(monthMoney.multiply(new BigDecimal(String.valueOf(pCount-1)))).add(actualDeposit.multiply(new BigDecimal(String.valueOf(yaCount)))));//账单金额
                    map.put("IfAdjust", 0);//当前账单是否可以调整   0.否  1.是\n水电燃房租不可调整  类型 1-2
                    map.put("TenId", params.get("TenId"));//租客编号
                    map.put("HouId", params.get("HouId"));//房源主表编号
                    map.put("HouInfoId", params.get("HouInfoId"));//房源详表编号
                    map.put("CreateType", 1);//账单创建人类型  1.系统  2.人为
                    map.put("Create", "auto");//账单创建人
                    map.put("ExpStatus", 0);//账单逾期状态 0未逾期， 1逾期 超过最晚状态还未支付
                    // map.put("ExpTime",0);//账单逾期开始时间
                    map.put("Status", 1);//账单状态   1.待支付  2.支付完成
                    map.put("BiName", "第1次房租账单");//首月账单名称
                    map.put("FirstMon", 1);//房租账单是否是首月    0否   1.是
                    map.put("term", "4");// 创建端 Insert端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
                    map.put("fnc",
                            this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
                    ParamsCommon.commonInsertParms(map);
                    //生成首月账单
                    seTenantBillMapper.addTenantBill(map);
                    //生成首月账单
                    Map<String, Object> uuid2 = utilsMapper.getUUID(new HashMap<String, Object>() {{
                        put("uuid", "BiId");
                        put("database", Constants.DATA_SOURCE_GMIO);
                        put("surface", "tcgmio_tenant_bill");
                    }});
                    if (uuid2 != null && (!uuid2.get("uuid").toString().equals(""))) {
                        int number = Integer.valueOf(uuid2.get("uuid").toString());
                        UUID2 = ComUtils.getLocalTrmSeqNum("tem", number);
                    } else {
                        UUID2 = ComUtils.getLocalTrmSeqNum("tem", 0);
                    }
                    Map<String, Object> liMap = new HashMap<String, Object>();
                    liMap.put("TemId", UUID2);//临时账单编号
                    liMap.put("CorId", params.get("CorId"));//房源所属的公司编号
                    liMap.put("TemType", 2);//临时账单类型   1.业主违约单   2.房租押金  3.水电押金
                    liMap.put("SourceId", UUID);//临时账单来源编号,根据账单类型 这里是账单主表编号
                    liMap.put("HouId", params.get("HouId"));//房源主表编号
                    liMap.put("HouInfoId", params.get("HouInfoId"));//房源详表编号
                    liMap.put("TenType", 2);//租客类型   1.业主  2.租客
                    liMap.put("TenId", params.get("TenId"));//租客编号   业主-租客',
                    //liMap.put("Cost",  monthMoney.multiply(new BigDecimal(String.valueOf(yaCount))));//应缴费用
                    liMap.put("Cost",  actualDeposit.multiply(new BigDecimal(String.valueOf(yaCount))));//应缴费用
                    liMap.put("Remark", 2);//临时账单备注
                    liMap.put("SysUserId", 2);//临时账单发起人编号
                    liMap.put("term", "4");// 创建端 Insert端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
                    liMap.put("fnc",
                            this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
                    ParamsCommon.commonInsertParms(liMap);
                    seTemporaryMapper.addSeTemporary(liMap);//新增房源 临时账单
//                    if (paCount > 1) {
                    //合同开始时间
                    dateParam = params.get("bottomADate").toString();
                    date = DateUtils.stringToDate(dateParam, "yyyy-MM-dd");
                    //组装集合
                    List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
                    map.put("BillExplain", "房租" +monthMoney.multiply(new BigDecimal(String.valueOf(pCount))));//账单金额说明
                    map.put("BiMoney", monthMoney.multiply(new BigDecimal(String.valueOf(pCount))));//账单金额
                    map.put("IfTemporary", 0);//是否是临时账单    0.否   1.是\n没有关联来源',
                    for (int i = 1; i < paCount; i++) {
                        Map<String, Object> listMap = new HashMap<String, Object>();
                        if (uuid != null && (!uuid.get("uuid").toString().equals(""))) {
                            int number = Integer.valueOf(uuid.get("uuid").toString());
                            UUID = ComUtils.getLocalTrmSeqNum("bi" + i, number);
                        } else {
                            UUID = ComUtils.getLocalTrmSeqNum("bi" + i, 0);
                        }
                        listMap.putAll(map);
                        listMap.put("BiName", "第" + (i + 1) + "次" + "房租账单");
                        listMap.put("BiId", UUID);//账单编号
                        listMap.put("FirstMon", 0);//房租账单是否是首月    0否   1.是
                        listMap.put("DepositType", 1);//房租类型   1.房租房租押金   2.水电押金   (账单类型为1)
                        listMap.put("BiGenerated", DateUtils.format(DateUtils.addDateMonths(date, (i * pCount))));//账单生成时间
                        listMap.put("EndTime", DateUtils.format(DateUtils.addDateMonthsToEnd(date, ((i + 1) * pCount))));//账单结束时间
                        listMap.put("LateDay", listMap.get("BiGenerated"));//账单最晚付款日
                        list.add(listMap);
                    }
                    System.out.println("之前:" + list);
                    if (yueCont > 0) {//如果有剩余就取集合最后一个元素设置账单金额
                        Map<String, Object> bMap = (Map<String, Object>) list.get(list.size() - 1);
                        bMap.put("BiMoney",monthMoney.multiply(new BigDecimal(String.valueOf(yueCont))));
                        bMap.put("BillExplain", "房租:" + monthMoney.multiply(new BigDecimal(String.valueOf(yueCont))));//账单金额说明
                    }
                    System.out.println("之后:" + list);
                    //水电首月押金
                    Map<String, Object> weMap = new HashMap<String, Object>();
                    weMap.putAll(map);
                    //水电押金账单编号
                    if (uuid != null && (!uuid.get("uuid").toString().equals(""))) {
                        int number = Integer.valueOf(uuid.get("uuid").toString());
                        UUID = ComUtils.getLocalTrmSeqNum("bi" + paCount + 1, number);
                    } else {
                        UUID = ComUtils.getLocalTrmSeqNum("bi" + paCount + 1, 0);
                    }
                    weMap.put("BiId", UUID);
                    weMap.put("BiName", "水电押金账单");
                    weMap.put("DepositType", 2);//房租类型   1.房租房租押金   2.水电押金   (账单类型为1)
                    weMap.put("BiMoney", WaDeposit);//水电押金金额
                    weMap.put("BillExplain", "水电押金:" + WaDeposit);//水电押金金额
                    list.add(weMap);
                    //map设置参数
                    map.put("billList", list);
                    map.put("BiName", "第一个月");
                    map.put("DepositType", 2);//房租类型   1.房租房租押金   2.水电押金   (账单类型为1)
                    map.put("BiId", UUID);//账单编号
                    map.put("BiGenerated", map.get("BiGenerated"));//账单生成时间
                    map.put("LateDay", map.get("BiGenerated"));//账单最晚付款日
                    int resultCount = seTenantBillMapper.addTenantBillForPact(map) + 1;
                    if (resultCount == paCount + 1) {
                        result.put("操作成功");
                    } else {
                        result.putFailed("操作失败");
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    }

                   if (WaterPricings.intValue()>0) {
                       this.addFixedWater(params);
                   }
                   if (GasPricings.intValue()>0) {
                       this.addFixedGas(params);
                   }
                   if(BroadBand.intValue()>0) {
                       this.addFixedNet(params);
                   }

                } else {
                   result.put("操作成功");


                }
//                }

            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        } finally {
            lock.unlock();
            System.out.println("返回给市场部的内容:" + result);
        }
        return result;
    }
    /**
     * 运营助理获取房间钥匙(查看)
     */
    public JsonResult getRdIntePassWord(Map<String,Object> params){
        JsonResult result=new JsonResult();
        if (params.get("HouConId")==null || params.get("HouId")==null
                ||params.get("BiMoney")==null || params.get("TenId")==null || params.get("CorId")==null||
                params.get("HouInfoId")==null || params.get("openid")==null || params.get("tInfo")==null){
            return result.putFailed("参数不正确");
        }
        //判断当前时间是否在08:30---20:00
        String format = "HH:mm:ss";
        SimpleDateFormat sf = new SimpleDateFormat("HH:mm:ss");
        String now = sf.format(new Date());
        Boolean iFBill=false;//是否需要账单
        try {
            Date nowTime = new SimpleDateFormat(format).parse(now);
//            Date nowTime = sf.parse("07:00:00");
            Date startTime = sf.parse("08:30:00");//免开门费 开始时间
            Date endTime = sf.parse("20:00:00");//免开门费 结束时间
            iFBill=DateUtils.isEffectiveDate(nowTime,startTime,endTime);
        } catch (java.text.ParseException e) {
            log.debug("时间转换错误");
            return result.putFailed("时间转换错误");
        }
        System.out.println("是否需要账单:"+iFBill);
        //判断是否需要夜间开门费的账单
        if (iFBill==false){//iFBill false需要夜间开门费账单 true 不需要账单
            //获取账单编号
            String UID="";
            Map<String, Object> uuid = utilsMapper.getUUID(new HashMap<String, Object>() {{
                put("uuid", "BiId");
                put("database", Constants.DATA_SOURCE_GMIO);
                put("surface", "tcgmio_tenant_bill");
            }});
            if (uuid != null && (!uuid.get("uuid").toString().equals(""))) {
                int number = Integer.valueOf(uuid.get("uuid").toString());
                UID = ComUtils.getLocalTrmSeqNum("bi" + 0, number);
            } else {
                UID = ComUtils.getLocalTrmSeqNum("bi" + 0, 0);
            }
            params.put("BiId",UID);//账单编号
            params.put("BiName","夜间开门费账单");
            params.put("IfTemporary","0");
            params.put("BiType","7");//账单类型  1.房租 2.公共事业费  3.维修费用  \n4.延期退审核  5.其他费用  6.退租账单
            params.put("by", ContextUtils.getUserId());//操作人
            params.put("term", "4");// 创建端 Insert端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
            params.put("fnc",
                    this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
            ParamsCommon.commonInsertParms(params);
            params.put("Status","1");//账单状态   1.待支付  2.支付完成  3待审核   4.账单废弃（租客违约）
            params.put("Abnormal","0");//账单异常状态   0正常   1异常
            params.put("BillExplain","夜间开门费:"+params.get("BiMoney"));//费用说明
            params.put("BiGenerated",params.get("instm"));//账单生成日期
            params.put("StaTime",params.get("instm"));//账单周期--开始时间
            params.put("CreateType","2");//账单创建人类型  1.系统  2.人为
            params.put("Create",params.get("insby"));//操作人编号
            try {
                params.put("EndTime",InteDeviceLockUtil.getTimeAfter(Long.valueOf(InteDeviceLockUtil.getTimeSign(params.get("instm").toString(),"yyyy-MM-dd HH:mm:ss")),2*3600*1000,"yyyy-MM-dd HH:mm:ss"));//账单周期--结束时间
            } catch (Exception e) {
                log.debug("日期转换出错");
                return result.putFailed("日期转换出错");
            }
            params.put("LateDay",params.get("EndTime"));//最晚付款时间
            params.put("IfAdjust",0);//当前账单是否可以调整   0.否  1.是
            seTenantBillMapper.addTenantBill(params);
        }
        //组装维修推送参数
        Map<String,Object> weiMap=new HashMap<String,Object>();
        weiMap.put("keyword1",new TemplateData(params.get("tInfo").toString(),"#4876FF"));//房源地址
        weiMap.put("first", new TemplateData("欢迎入住唐巢公寓，您的开门密码如下，此密码在收到后" +
                "的两小时内有效，且只能输入一次，在门锁按键输入'密码+#'后便可开门", "#4876FF"));
        JsonResult marketResult=zpcEpcFeign.getHoInteHouConInfoList(params);
        List<Map<String,Object>> IdentifierList=(List<Map<String,Object>>)marketResult.get("result");
        System.out.println("IdentifierList:"+IdentifierList);
        if (marketResult.get("errorCode").toString().equals("0")){
            if (IdentifierList==null){
                log.debug("缺少智能设备编号:IdentifierList");
                return result.putFailed("服务器繁忙");
            }
            int num=0;
            int num2=0;//科技侠
            for (Map<String,Object> InteMap:IdentifierList){
                //Intelligent 0.蜂电   1.大华   2.科技侠   3.果加
                if (InteMap.get("Intelligent").toString().equals("2")){
                    String DeviceLockToken=redisUtils.get("DeviceLockToken");
                    //如果获取不到就重新登录
                    if (DeviceLockToken==null){
                        Map<String,Object> tokenMap=new HashMap<String, Object>();
                        params.put("client_id",InteDeviceLockConfig.CLIENT_ID);
                        params.put("client_secret",InteDeviceLockConfig.CLIENT_SECRET);
                        params.put("grant_type",InteDeviceLockConfig.GRANT_TYPE_PASSWORD);
                        params.put("username",InteDeviceLockConfig.USERNAME);
                        params.put("password",InteDeviceLockConfig.PASSWORD);
                        params.put("redirect_uri",InteDeviceLockConfig.REDIRECT_URL);
                        tokenMap=InteDeviceLockUtil.oauth2Token(params);
                        if (tokenMap.get("access_token")!=null){
                            DeviceLockToken=tokenMap.get("access_token").toString();
                            //token存到redis中
                            redisUtils.set("DeviceLockToken",DeviceLockToken,Long.valueOf(tokenMap.get("expires_in").toString()));
                        }else{
                            return result.putFailed("token获取失败");
                        }
                    }
                    num2++;
                    params.put("clientId", InteDeviceLockConfig.CLIENT_ID);//应用编号
                    params.put("accessToken",DeviceLockToken);//访问令牌
                    params.put("lockId",InteMap.get("Identifier"));//智能设备编号
                    params.put("keyboardPwdVersion","4");//键盘密码版本, 三代锁的密码版本为4
                    params.put("keyboardPwdType","1");//参数值 单次	1
                    //密码有效时间
                    //获取当前时间
                    params.put("startDate", InteDeviceLockUtil.getTimeSign(InteDeviceLockUtil.getTimeAfter(System.currentTimeMillis(),0,"yyyy-MM-dd HH:mm:ss"),"yyyy-MM-dd HH:mm:ss"));
                    //获取一个小时之后的时间
                    params.put("endDate",InteDeviceLockUtil.getTimeSign(InteDeviceLockUtil.getTimeAfter(System.currentTimeMillis(),2*60*60*1000,"yyyy-MM-dd HH:mm:ss"),"yyyy-MM-dd HH:mm:ss"));
                    params.put("date",InteDeviceLockUtil.getTimeSign());
                    System.out.println("params:"+params);
                    Map<String,Object> map= InteDeviceLockUtil.keyboardPwdGet(params);
                    System.out.println("map:"+map);
                    if (map.get("keyboardPwd")!=null){
                        //HouConType 房源配置类型 1公共区域 2房间 3整租
                        if (InteMap.get("HouConType").toString().equals("1")){
                            weiMap.put("keyword2",new TemplateData(map.get("keyboardPwd").toString(), "#4876FF"));
                        }else if (InteMap.get("HouConType").toString().equals("2")){
                            weiMap.put("keyword3",new TemplateData(map.get("keyboardPwd").toString(), "#4876FF"));
                        }
                        InteMap.putAll(map);
                        num++;
                    }else{
                        return result.putFailed("服务器繁忙");
                    }
                }else if(InteMap.get("Intelligent").toString().equals("3")){
                    String GuoJiaToken=redisUtils.get("GuoJiaToken");
                    //如果获取不到就重新登录
                    if (GuoJiaToken==null){
                        Map<String,Object> guoJiaMap=new HashMap<String, Object>();
                        guoJiaMap.put("s_id",InteGuoJiaUtil.getSid());
                        guoJiaMap.put("version","1");
                        com.alibaba.fastjson.JSONObject bodyJson=new com.alibaba.fastjson.JSONObject();
                        //key
                        DESEncrypt desPlus2 = new DESEncrypt(InteGuoJiaConfig.DES_KEY);
                        //密码
                        bodyJson.put("account",InteGuoJiaConfig.ACCOUNT);
                        bodyJson.put("password",desPlus2.encrypt(InteGuoJiaConfig.PASSWORD));
                        guoJiaMap=InteGuoJiaUtil.login(guoJiaMap,bodyJson);
                        //返回的token数据
                        Map<String,Object>dataMap=(Map<String,Object>)guoJiaMap.get("data");
                        if (guoJiaMap.get("rlt_code").toString().equals("HH0000")){//HH0000 、成功
                            GuoJiaToken=dataMap.get("access_token").toString();
                            //token存到redis中
                            redisUtils.set("GuoJiaToken",GuoJiaToken,Long.valueOf(dataMap.get("expires_second").toString()));
                        }else{
                            return result.putFailed("token获取失败");
                        }
                    }
                    num2++;
                    Map<String,Object> guoJiaMap=new HashMap<String, Object>();
                    guoJiaMap.put("s_id", InteGuoJiaUtil.getSid());
                    guoJiaMap.put("version","1");
                    guoJiaMap.put("access_token",GuoJiaToken);
                    com.alibaba.fastjson.JSONObject bodyJson=new com.alibaba.fastjson.JSONObject();
                    bodyJson.put("lock_no",InteMap.get("Identifier"));//智能设备编号
                    bodyJson.put("pwd_user_mobile","13020100801");
                    System.out.println("guoJiaMap:"+guoJiaMap);
                    //发送键密码
                    Map<String,Object> map=InteGuoJiaUtil.temp_pwd(guoJiaMap,bodyJson);
                    DESEncrypt desPlus2 = new DESEncrypt(InteGuoJiaConfig.DES_KEY);
                    String d2="";
                    try {
                        Map<String,Object> dataMap=(Map<String,Object>)map.get("data");
                        d2 = desPlus2.decrypt(DESEncrypt.byteArr2HexStr(DESEncrypt.hexStringToBytes(dataMap.get("pwd_text").toString())));
                    }catch (Exception e){
                        log.debug("键盘密码解密错误"+e);
                    }
                    if (map.get("rlt_code").toString().equals("HH0000")){//HH0000 请求成功
                        if (InteMap.get("HouConType").toString().equals("1")){
                            weiMap.put("keyword2",new TemplateData(d2, "#4876FF"));
                        }else if (InteMap.get("HouConType").toString().equals("2")){
                            weiMap.put("keyword3",new TemplateData(d2, "#4876FF"));
                        }
                        InteMap.put("keyboardPwd",d2);
                        InteMap.putAll(map);
                        num++;
                    }else{
                        return result.putFailed("服务器繁忙");
                    }
                    InteMap.putAll(map);
                }
            }
            System.out.println("weiMap："+weiMap);
            Jsapi_ticketUtil.sendTemplate(params.get("openid").toString(), WeChatConfig.SEND_KEY,"","#4876FF", JSONObject.fromObject(weiMap));
            //判断是系统还是租客
//            if (params.get("checktype").toString().equals("2")){
            if (num==num2){
                result.put(IdentifierList);
            }else{
                result.putFailed("服务器繁忙");
            }
//            }
            return result;
        }else{//如果市场部异常就直接返回出去
            return marketResult;
        }
    }
    /**
     * 通过客户编号查询账单列表
     */
    @Override
    public JsonResult getTenantBillListByTenIdwd(Map<String, Object> params) {
        JsonResult result=new JsonResult();
        //查询待审核的账单
        List<Map<String,Object>> list=seTenantBillMapper.getTenantBillListByTenId(params);
        //保存合同编号集合
        List<String> PaIdList=new ArrayList<String>();
        for (Map<String,Object> map: list){
            if(map.get("Source")!=null){
                PaIdList.add(map.get("Source").toString());
            }
        }
        params.put("PaIdList",PaIdList);
        System.out.println("list:"+list);
        //去市场部查询房源的合同信息
        JsonResult marketResult=zpcMktFeign.getRdPactTrade(params);
        System.out.println("marketResult:"+marketResult);
        if (marketResult.get("errorCode").toString().equals("0")) {
            List<Map<String, Object>> marketList = (List<Map<String, Object>>) marketResult.get("result");
            for (Map<String, Object> map1 : list) {
                if (map1.get("Source") != null) {
                    for (Map<String, Object> map2 : marketList) {
                        if (map2.get("PaId") != null) {
                            if (map1.get("Source").toString().equals(map2.get("PaId").toString())) {
                                map1.putAll(map2);
                            }
                        }
                    }
                }
            }
        }
        if (list!=null){
            result.put(list);
        }else{
            result.putFailed("服务器繁忙");
        }

        return result;
    }
    /**
     * 租后主管查询人员管理（秘书角色）
     */
    @Override
    public JsonResult getSeTenantBillList(Map<String, Object> params) {
        JsonResult result=new JsonResult();
        params.put("role_id","9");//服务秘书的编号
        //运营部的数据
        List<Map<String,Object>> gmioList=seTenantBillMapper.getSeTenantBillList(params);
        //查询网关里秘书相关的数据
        JsonResult zuulResult=zzuulFeign.getSysDeptRoleList(params);
        System.out.println("网关返回的值:"+zuulResult);
        if(zuulResult.get("errorCode")==null || !zuulResult.get("errorCode").toString().equals("0")){
            return result.putFailed("服务器繁忙");
        }
        //网关的集合
        List<Map<String,Object>> zuulList=(List<Map<String,Object>>)zuulResult.get("result");
        //和运营部的集合匹配
        for (Map<String,Object> map1:zuulList) {
            if (map1.get("user_id") != null) {
                for (Map<String, Object> map2 : gmioList) {
                    if (map2.get("AuditId") != null) {
                        if (String.valueOf(map1.get("user_id")).equals(String.valueOf(map2.get("AuditId")))) {
                            System.out.println("比对成功");
                            map1.putAll(map2);
                        }
                    }
                }
            }
        }
        if (zuulList!=null){
            result.put(zuulList);
        }else{
            result.putFailed("服务器繁忙");
        }
        return result;
    }

    /**
     * @return java.util.List<java.util.Map   <   java.lang.String   ,   java.lang.Object>>
     * @Description //TODO 查询用户已支付的订单列表
     * @Param [params]
     * @Date 2019/4/28 15:55
     **/
    @Override
    public List<Map<String, Object>> listTenantBillHavePaid(Map<String, Object> params) {
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        //查询用户已支付的账单的列表,发票管理
        List<Map<String, Object>> listTenantBillHavePaid = seTenantBillMapper.listTenantBillHavePaid(params);
        //获取所有房源资料
        JsonResult jsonResult = zpcMktFeign.getAllHousingList();
        if (jsonResult.isSuccess() == true) {
            List<Map<String, Object>> getAllHousingList = (List<Map<String, Object>>) jsonResult.getResult();
            result = ListMapMergeUtil.ListMergeUtils(listTenantBillHavePaid, getAllHousingList, "HouInfoId");
        } else {
            result = listTenantBillHavePaid;
        }
        JsonResult jsonResult1 = CfoFeign.listTenantHaveInvoiceBill(params);
        if (jsonResult1.isSuccess() == true) {
            List<Map<String, Object>> listTenantHaveInvoiceBill = (List<Map<String, Object>>) jsonResult1.getResult();
            //判断是否已开票
            for (Map<String, Object> map : result) {
                String biId = (String) map.get("BiId");
                if (listTenantHaveInvoiceBill.size() > 0) {
                    for (Map<String, Object> map1 : listTenantHaveInvoiceBill) {
                        String biId1 = (String) map1.get("BiId");
                        if (biId.equals(biId1)) {
                            map.put("haveInvoice", 1);
                            map.put("Status", map1.get("Status").toString());
                            break;
                        } else {
                            map.put("haveInvoice", 0);
                            map.put("Status", "0");
                        }
                    }
                } else {
                    map.put("haveInvoice", 0);
                    map.put("Status", "0");
                }
            }
        } else {
            for (Map<String, Object> map : result) {
                map.put("haveInvoice", 0);
                map.put("Status", "0");
            }
        }
        return result;

    }

    /**
     * 功能描述:
     * 查询用户已支付的订单列表总条数
     *
     * @Author zhlu
     * @Description //TODO
     * @Date 2019/5/5 16:00
     */
    public Integer getTenantBillHavePaidCount(Map<String, Object> params) {
        return seTenantBillMapper.getTenantBillHavePaidCount(params);
    }


    /**
     * 固定金额的水费
     * @author zhoucong
     * @data 2019/11/14
     * @Param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public JsonResult addFixedWater (Map<String,Object> params){
        JsonResult result = new JsonResult();
        Integer coutWater = new Integer("0");
        /**
         *加锁操作
         */
        lock.lock();
        try {

            //获取账单编号
            Map<String, Object> uuid = utilsMapper.getUUID(new HashMap<String, Object>() {{
                put("uuid", "BiId");
                put("database", Constants.DATA_SOURCE_GMIO);
                put("surface", "tcgmio_tenant_bill");
            }});

            //合同开始时间
            DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
            String dateParam = params.get("bottomADate").toString();
            //Date date = DateUtils.stringToDate(dateParam, "yyyy-MM-dd");
            Date date = format1.parse(dateParam);



            Integer paCount = MapUtils.getInteger(params,"paCount");//合同周期内需要交房租次数
            Integer pCount = MapUtils.getInteger(params,"pCount");//每次需要交房租的月数
            Integer yueCont =  MapUtils.getInteger(params,"yueCont");//最后一次账单需要交的月份

            if(paCount==1){//如果只用交一次
                Map<String,Object>  map = new HashMap<>();
                if (uuid != null && (!uuid.get("uuid").toString().equals(""))) {
                    int number = Integer.valueOf(uuid.get("uuid").toString());
                    UUID = ComUtils.getLocalTrmSeqNum("BiWat"+1, number);
                } else {
                    UUID = ComUtils.getLocalTrmSeqNum("BiWat"+1, 0);
                }
                map.put("BiId",UUID);//水费账单编号
                map.put("CorId",params.get("CorId"));//当前账单归属公司
                map.put("BiName","第1次固定水费账单");//账单名称
                map.put("BiType",2);//账单类型
                map.put("FirstMon",1);//是否首月（0否 1是）
                map.put("Source",params.get("PaId"));//来源编号
                map.put("PubType",1);//公共事业费类型
                map.put("BiGenerated",params.get("bottomADate"));//账单生成日
                map.put("LateDay",DateUtils.addDateDays(DateUtils.stringToDate(map.get("BiGenerated").toString(),"yyyy-MM-dd"),15));//账单最晚付款日 生成日往后加15天
                if(yueCont>0){
                   //账单金额(最后一次账单需要交的月份*固定金额)
                    map.put("BiMoney",new BigDecimal(String.valueOf(yueCont)).multiply(new BigDecimal(params.get("WaterPricings").toString())));
                    map.put("EndTime",DateUtils.format(DateUtils.addDateMonthsToEnd(date,yueCont)));//账单结束时间
                    map.put("BillExplain",yueCont+"个月的水费金额");//账单说明
                }else{
                   //账单金额（固定金额*付款周期）
                    map.put("BiMoney",new BigDecimal(String.valueOf(pCount)).multiply(new BigDecimal(params.get("WaterPricings").toString())));
                    map.put("EndTime",DateUtils.format(DateUtils.addDateMonthsToEnd(date,pCount)));//账单结束时间
                    map.put("BillExplain",pCount+"个月的水费金额");//账单说明
                }
                map.put("IfAdjust",0);//当前账单是否可以调整 0.否  1.是
                map.put("TenId",params.get("TenId"));//租客id
                map.put("HouId",params.get("HouId"));//房源id
                map.put("HouInfoId",params.get("HouInfoId"));//房源详表编号
                map.put("CreateType",1);//账单创建人类型1，系统 2 人为
                map.put("ExpStatus",0);//账单逾期状态   0.未逾期  1逾期   （超过最晚状态还未支付）',
                map.put("ExpTime",map.get("LateDay"));//逾期开始时间，账单什么时候逾期的时间，\n如果超过12个小时，停门卡,同时可以强制退租
                map.put("term", "4");// 创建端 Insert端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
                map.put("fnc",
                        this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
                ParamsCommon.commonInsertParms(map);
                Integer  cout = seTenantBillMapper.addTenantBill(map);
                if (cout<=0){
                    result.putFailed("新增水费账单失败");
                }else{
                    result.putSuccess("新增水费账单成功");
                }

            }else{//说明合同周期内不止一次需要付款
                    for(int a =1;a<=paCount;a++){
                        Map<String,Object>  map = new HashMap<>();
                        if (uuid != null && (!uuid.get("uuid").toString().equals(""))) {
                            int number = Integer.valueOf(uuid.get("uuid").toString());
                            UUID = ComUtils.getLocalTrmSeqNum("BiWat"+a, number);
                        } else {
                            UUID = ComUtils.getLocalTrmSeqNum("BiWat"+a, 0);
                        }
                        map.put("BiId",UUID);//水费账单编号
                        map.put("CorId",params.get("CorId"));//当前账单归属公司
                        map.put("BiName","第"+a+"次固定水费账单");//账单名称
                        map.put("BiType",2);//账单类型
                        map.put("Source",params.get("PaId"));//来源编号
                        map.put("PubType",1);//公共事业费类型
                        if(a==1){
                            map.put("BiGenerated",dateParam);//第一次账单生成日
                            map.put("FirstMon",1);//是否首月（0否 1是）
                            map.put("LateDay",DateUtils.addDateDays(DateUtils.stringToDate(dateParam,"yyyy-MM-dd"),15));//账单最晚付款日 生成日往后加15天
                            map.put("EndTime",DateUtils.addDateMonthsToEnd(DateUtils.stringToDate(dateParam,"yyyy-MM-dd"),pCount));//不到最后一次账单的结束时间

                        }else{
                            //map.put("BiGenerated",DateUtils.addDateMonthsToEnd(date,(a-1)*pCount));//其他月份的账单生成日
                            map.put("BiGenerated",DateUtils.addDateDays(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),1));//其他月份的账单生成日
                            map.put("LateDay",DateUtils.addDateDays(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),15));//账单最晚付款日 生成日往后加15天
                           // map.put("EndTime",DateUtils.addDateMonthsToEnd(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),pCount));//不到最后一次账单的结束时间
                            map.put("EndTime", DateUtils.addDateDays(DateUtils.addDateMonthsToEnd(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),pCount),1));//不到最后一次账单的结束时间
                        }
                        map.put("BillExplain",pCount+"个月的水费金额");//账单说明
                        if(a==paCount){
                        map.put("EndTime",params.get("endADate"));//最后一次账单的结束时间 （合同结束时间）
                       }

                        if (a==paCount&&yueCont>0){
                            map.put("BiMoney",new BigDecimal(String.valueOf(yueCont)).multiply(new BigDecimal(params.get("WaterPricings").toString())));//最后一次账单金额
                            map.put("BillExplain",yueCont+"个月的水费金额");//账单说明
                        }else{
                            map.put("BiMoney",new BigDecimal(String.valueOf(pCount)).multiply(new BigDecimal(params.get("WaterPricings").toString())));//最后一次账单金额
                        }
                        map.put("IfAdjust",0);//当前账单是否可以调整 0.否  1.是
                        map.put("TenId",params.get("TenId"));//租客id
                        map.put("HouId",params.get("HouId"));//房源id
                        map.put("HouInfoId",params.get("HouInfoId"));//房源详表编号
                        map.put("CreateType",1);//账单创建人类型1，系统 2 人为
                        map.put("ExpStatus",0);//账单逾期状态   0.未逾期  1逾期   （超过最晚状态还未支付）',
                        map.put("ExpTime",map.get("LateDay"));//逾期开始时间，账单什么时候逾期的时间，\n如果超过12个小时，停门卡,同时可以强制退租
                        map.put("term", "4");// 创建端 Insert端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
                        map.put("fnc",
                                this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
                        ParamsCommon.commonInsertParms(map);

                        Integer cout = seTenantBillMapper.addTenantBill(map);
                        if (cout<=0){
                            result.putFailed("新增水费账单失败");
                        }else{
                            coutWater++;
                        }

                    }
                    if (coutWater==paCount){
                        result.putSuccess("新增水费账单成功");
                    }else{
                        result.putFailed("新增水费账单失败");
                    }
                }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//事务回滚
        } finally {
            lock.unlock();
        }
         return result;

    }


    /**
     * 获取固定金额的燃气费
     * @param params
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public JsonResult  addFixedGas(Map<String,Object> params){

        JsonResult result = new JsonResult();
        Integer coutGas = new Integer("0");
        /**
         *加锁操作
         */
        lock.lock();
        try {

            //获取燃气账单编号
            Map<String, Object> uuid = utilsMapper.getUUID(new HashMap<String, Object>() {{
                put("uuid", "BiId");
                put("database", Constants.DATA_SOURCE_GMIO);
                put("surface", "tcgmio_tenant_bill");
            }});

            //合同开始时间
            DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
            String dateParam = params.get("bottomADate").toString();
           // Date date = DateUtils.stringToDate(dateParam, "yyyy-MM-dd");
            Date date = format1.parse(dateParam);

            Integer paCount = MapUtils.getInteger(params,"paCount");//合同周期内需要交房租次数
            Integer pCount = MapUtils.getInteger(params,"pCount");//每次需要交房租的月数
            Integer yueCont =  MapUtils.getInteger(params,"yueCont");//最后一次账单需要交的月份

            if(paCount==1){//如果只用交一次
                Map<String,Object>  map = new HashMap<>();
                if (uuid != null && (!uuid.get("uuid").toString().equals(""))) {
                    int number = Integer.valueOf(uuid.get("uuid").toString());
                    UUID = ComUtils.getLocalTrmSeqNum("BiGas"+1, number);
                } else {
                    UUID = ComUtils.getLocalTrmSeqNum("BiGas"+1, 0);
                }
                map.put("BiId",UUID);//燃气费账单编号
                map.put("CorId",params.get("CorId"));//当前账单归属公司
                map.put("BiName","第1次固定燃气费账单");//账单名称
                map.put("BiType",2);//账单类型
                map.put("FirstMon",1);//是否首月（0否 1是）
                map.put("Source",params.get("PaId"));//来源编号
                map.put("PubType",3);//公共事业费类型
                map.put("BiGenerated",params.get("bottomADate"));//账单生成日
                map.put("LateDay",DateUtils.addDateDays(DateUtils.stringToDate(map.get("BiGenerated").toString(),"yyyy-MM-dd"),15));//账单最晚付款日 生成日往后加15天
                if(yueCont>0){
                    //账单金额(最后一次账单需要交的月份*固定金额)
                    map.put("BiMoney",new BigDecimal(String.valueOf(yueCont)).multiply(new BigDecimal(params.get("GasPricings").toString())));
                    map.put("EndTime",DateUtils.format(DateUtils.addDateMonthsToEnd(date,yueCont)));//账单结束时间
                    map.put("BillExplain",yueCont+"个月的燃气费金额");//账单说明
                }else{
                    //账单金额（固定金额*付款周期）
                    map.put("BiMoney",new BigDecimal(String.valueOf(pCount)).multiply(new BigDecimal(params.get("GasPricings").toString())));
                    map.put("EndTime",DateUtils.format(DateUtils.addDateMonthsToEnd(date,pCount)));//账单结束时间
                    map.put("BillExplain",pCount+"个月的燃气费金额");//账单说明
                }
                map.put("IfAdjust",0);//当前账单是否可以调整 0.否  1.是
                map.put("TenId",params.get("TenId"));//租客id
                map.put("HouId",params.get("HouId"));//房源id
                map.put("HouInfoId",params.get("HouInfoId"));//房源详表编号
                map.put("CreateType",1);//账单创建人类型1，系统 2 人为
                map.put("ExpStatus",0);//账单逾期状态   0.未逾期  1逾期   （超过最晚状态还未支付）',
                map.put("ExpTime",map.get("LateDay"));//逾期开始时间，账单什么时候逾期的时间，\n如果超过12个小时，停门卡,同时可以强制退租
                map.put("term", "4");// 创建端 Insert端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
                map.put("fnc",
                        this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
                ParamsCommon.commonInsertParms(map);
                Integer  cout = seTenantBillMapper.addTenantBill(map);
                if (cout<=0){
                    result.putFailed("新增燃气费费账单失败");
                }else{
                    result.putSuccess("新增燃气费账单成功");
                }

            }else{//说明合同周期内不止一次需要付款
                for(int a =1;a<=paCount;a++){
                    Map<String,Object>  map = new HashMap<>();
                    if (uuid != null && (!uuid.get("uuid").toString().equals(""))) {
                        int number = Integer.valueOf(uuid.get("uuid").toString());
                        UUID = ComUtils.getLocalTrmSeqNum("BiGas"+a, number);
                    } else {
                        UUID = ComUtils.getLocalTrmSeqNum("BiGas"+a, 0);
                    }
                    map.put("BiId",UUID);//燃气费账单编号
                    map.put("CorId",params.get("CorId"));//当前账单归属公司
                    map.put("BiName","第"+a+"次固定燃气费账单");//账单名称
                    map.put("BiType",2);//账单类型
                    map.put("Source",params.get("PaId"));//来源编号
                    map.put("PubType",3);//公共事业费类型
                    if(a==1){
                        map.put("BiGenerated",dateParam);//第一次账单生成日
                        map.put("FirstMon",1);//是否首月（0否 1是）
                        map.put("LateDay",DateUtils.addDateDays(DateUtils.stringToDate(dateParam,"yyyy-MM-dd"),15));//账单最晚付款日 生成日往后加15天
                        map.put("EndTime",DateUtils.addDateMonthsToEnd(DateUtils.stringToDate(dateParam,"yyyy-MM-dd"),pCount));//不到最后一次账单的结束时间

                    }else{
                        //map.put("BiGenerated",DateUtils.addDateMonthsToEnd(date,(a-1)*pCount));//其他月份的账单生成日
                        map.put("BiGenerated",DateUtils.addDateDays(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),1));//其他月份的账单生成日
                        map.put("LateDay",DateUtils.addDateDays(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),15));//账单最晚付款日 生成日往后加15天
                      //  map.put("EndTime",DateUtils.addDateMonthsToEnd(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),pCount));//不到最后一次账单的结束时间
                        map.put("EndTime", DateUtils.addDateDays(DateUtils.addDateMonthsToEnd(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),pCount),1));//不到最后一次账单的结束时间
                    }

                    map.put("BillExplain",pCount+"个月的燃气费金额");//账单说明


                    if(a==paCount){
                        map.put("EndTime",params.get("endADate"));//最后一次账单的结束时间 （合同结束时间）
                    }

                    if (a==paCount&&yueCont>0){
                        map.put("BiMoney",new BigDecimal(String.valueOf(yueCont)).multiply(new BigDecimal(params.get("GasPricings").toString())));//最后一次账单金额
                        map.put("BillExplain",yueCont+"个月的燃气费金额");//账单说明
                    }else{
                        map.put("BiMoney",new BigDecimal(String.valueOf(pCount)).multiply(new BigDecimal(params.get("GasPricings").toString())));//最后一次账单金额
                    }
                    map.put("IfAdjust",0);//当前账单是否可以调整 0.否  1.是
                    map.put("TenId",params.get("TenId"));//租客id
                    map.put("HouId",params.get("HouId"));//房源id
                    map.put("HouInfoId",params.get("HouInfoId"));//房源详表编号
                    map.put("CreateType",1);//账单创建人类型1，系统 2 人为
                    map.put("ExpStatus",0);//账单逾期状态   0.未逾期  1逾期   （超过最晚状态还未支付）',
                    map.put("ExpTime",map.get("LateDay"));//逾期开始时间，账单什么时候逾期的时间，\n如果超过12个小时，停门卡,同时可以强制退租
                    map.put("term", "4");// 创建端 Insert端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
                    map.put("fnc",
                            this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
                    ParamsCommon.commonInsertParms(map);

                    Integer cout = seTenantBillMapper.addTenantBill(map);
                    if (cout<=0){
                        result.putFailed("新增燃气费账单失败");
                    }else{
                        coutGas++;
                    }

                }
                if (coutGas==paCount){
                    result.putSuccess("新增燃气费账单成功");
                }else{
                    result.putFailed("新增燃气费账单失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//事务回滚
        } finally {
            lock.unlock();
        }
        return result;
    }


    /**
     * 增加固定金额的宽带
     * @param params
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public JsonResult addFixedNet(Map<String,Object> params){

        JsonResult result = new JsonResult();
        Integer coutNet = new Integer("0");
        /**
         *加锁操作
         */
        lock.lock();
        try {

            log.info("生成固定宽带走的流程01");
            log.info("接收的参数");
            log.info("bottomADate"+params.get("bottomADate").toString());

            //获取账单编号
            Map<String, Object> uuid = utilsMapper.getUUID(new HashMap<String, Object>() {{
                put("uuid", "BiId");
                put("database", Constants.DATA_SOURCE_GMIO);
                put("surface", "tcgmio_tenant_bill");
            }});

            //合同开始时间

            //合同开始时间
            DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
            String dateParam = params.get("bottomADate").toString();
            // Date date = DateUtils.stringToDate(dateParam, "yyyy-MM-dd");
            Date date = format1.parse(dateParam);

            log.info("22222222222222222222222");
            log.info("dateParam"+dateParam);
            log.info("date"+date);

//            String dateParam = params.get("bottomADate").toString();
//            Date date = DateUtils.stringToDate(dateParam, "yyyy-MM-dd");

            Integer paCount = MapUtils.getInteger(params,"paCount");//合同周期内需要交房租次数
            Integer pCount = MapUtils.getInteger(params,"pCount");//每次需要交房租的月数
            Integer yueCont =  MapUtils.getInteger(params,"yueCont");//最后一次账单需要交的月份

            if(paCount==1){//如果只用交一次
                Map<String,Object>  map = new HashMap<>();
                if (uuid != null && (!uuid.get("uuid").toString().equals(""))) {
                    int number = Integer.valueOf(uuid.get("uuid").toString());
                    UUID = ComUtils.getLocalTrmSeqNum("BiNet"+1, number);
                } else {
                    UUID = ComUtils.getLocalTrmSeqNum("BiNet"+1, 0);
                }
                map.put("BiId",UUID);//宽带费账单编号
                map.put("CorId",params.get("CorId"));//当前账单归属公司
                map.put("BiName","第1次固定宽带费账单");//账单名称
                map.put("BiType",2);//账单类型
                map.put("FirstMon",1);//是否首月（0否 1是）
                map.put("Source",params.get("PaId"));//来源编号
                map.put("PubType",4);//公共事业费类型
                map.put("BiGenerated",params.get("bottomADate"));//账单生成日
                map.put("LateDay",DateUtils.addDateDays(DateUtils.stringToDate(map.get("BiGenerated").toString(),"yyyy-MM-dd"),15));//账单最晚付款日 生成日往后加15天
                if(yueCont>0){
                    //账单金额(最后一次账单需要交的月份*固定金额)
                    map.put("BiMoney",new BigDecimal(String.valueOf(yueCont)).multiply(new BigDecimal(params.get("BroadBand").toString())));
                    map.put("EndTime",DateUtils.format(DateUtils.addDateMonthsToEnd(date,yueCont)));//账单结束时间
                    map.put("BillExplain",yueCont+"个月的宽带费金额");//账单说明
                }else{
                    //账单金额（固定金额*付款周期）
                    map.put("BiMoney",new BigDecimal(String.valueOf(pCount)).multiply(new BigDecimal(params.get("BroadBand").toString())));
                    map.put("EndTime",DateUtils.format(DateUtils.addDateMonthsToEnd(date,pCount)));//账单结束时间
                    map.put("BillExplain",pCount+"个月的宽带费金额");//账单说明
                }
                map.put("IfAdjust",0);//当前账单是否可以调整 0.否  1.是
                map.put("TenId",params.get("TenId"));//租客id
                map.put("HouId",params.get("HouId"));//房源id
                map.put("HouInfoId",params.get("HouInfoId"));//房源详表编号
                map.put("CreateType",1);//账单创建人类型1，系统 2 人为
                map.put("ExpStatus",0);//账单逾期状态   0.未逾期  1逾期   （超过最晚状态还未支付）',
                map.put("ExpTime",map.get("LateDay"));//逾期开始时间，账单什么时候逾期的时间，\n如果超过12个小时，停门卡,同时可以强制退租
                map.put("term", "4");// 创建端 Insert端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
                map.put("fnc",
                        this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
                ParamsCommon.commonInsertParms(map);
                Integer  cout = seTenantBillMapper.addTenantBill(map);
                if (cout<=0){
                    result.putFailed("新增宽带费账单失败");
                }else{
                    result.putSuccess("新增宽带费账单成功");
                }

            }else{//说明合同周期内不止一次需要付款
                for(int a =1;a<=paCount;a++){
                    Map<String,Object>  map = new HashMap<>();
                    if (uuid != null && (!uuid.get("uuid").toString().equals(""))) {
                        int number = Integer.valueOf(uuid.get("uuid").toString());
                        UUID = ComUtils.getLocalTrmSeqNum("BiNet"+a, number);
                    } else {
                        UUID = ComUtils.getLocalTrmSeqNum("BiNet"+a, 0);
                    }
                    map.put("BiId",UUID);//宽带费账单编号
                    map.put("CorId",params.get("CorId"));//当前账单归属公司
                    map.put("BiName","第"+a+"次固定宽带费账单");//账单名称
                    map.put("BiType",2);//账单类型
                    map.put("Source",params.get("PaId"));//来源编号
                    map.put("PubType",4);//公共事业费类型
                    if(a==1){
                        log.info("111111111111111111111111");
                        log.info("dateParam"+dateParam);
                        map.put("BiGenerated",dateParam);//第一次账单生成日
                        map.put("FirstMon",1);//是否首月（0否 1是）
                        map.put("LateDay",DateUtils.addDateDays(DateUtils.stringToDate(dateParam,"yyyy-MM-dd"),15));//账单最晚付款日 生成日往后加15天
                        map.put("EndTime",DateUtils.addDateMonthsToEnd(DateUtils.stringToDate(dateParam,"yyyy-MM-dd"),pCount));//不到最后一次账单的结束时间

                    }else{
                        //map.put("BiGenerated",DateUtils.addDateMonthsToEnd(date,(a-1)*pCount));//其他月份的账单生成日
                        map.put("BiGenerated",DateUtils.addDateDays(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),1));//其他月份的账单生成日
                        map.put("LateDay",DateUtils.addDateDays(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),15));//账单最晚付款日 生成日往后加15天
                      //  map.put("EndTime",DateUtils.addDateMonthsToEnd(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),pCount));//不到最后一次账单的结束时间
                        map.put("EndTime", DateUtils.addDateDays(DateUtils.addDateMonthsToEnd(DateUtils.addDateMonthsToEnd(date,(a-1)*pCount),pCount),1));//不到最后一次账单的结束时间


                    }
                    map.put("BillExplain",pCount+"个月的宽带费金额");//账单说明
                    if(a==paCount){
                        map.put("EndTime",params.get("endADate"));//最后一次账单的结束时间 （合同结束时间）
                    }

                    if (a==paCount&&yueCont>0){
                        map.put("BiMoney",new BigDecimal(String.valueOf(yueCont)).multiply(new BigDecimal(params.get("BroadBand").toString())));//最后一次账单金额
                        map.put("BillExplain",yueCont+"个月的宽带费金额");//账单说明
                    }else{
                        map.put("BiMoney",new BigDecimal(String.valueOf(pCount)).multiply(new BigDecimal(params.get("BroadBand").toString())));//最后一次账单金额
                    }
                    map.put("IfAdjust",0);//当前账单是否可以调整 0.否  1.是
                    map.put("TenId",params.get("TenId"));//租客id
                    map.put("HouId",params.get("HouId"));//房源id
                    map.put("HouInfoId",params.get("HouInfoId"));//房源详表编号
                    map.put("CreateType",1);//账单创建人类型1，系统 2 人为
                    map.put("ExpStatus",0);//账单逾期状态   0.未逾期  1逾期   （超过最晚状态还未支付）',
                    map.put("ExpTime",map.get("LateDay"));//逾期开始时间，账单什么时候逾期的时间，\n如果超过12个小时，停门卡,同时可以强制退租
                    map.put("term", "4");// 创建端 Insert端： 1 租客端 2市场部 3 工程部   4运营部   5财务部  6总经办 7发展部
                    map.put("fnc",
                            this.getClass().getSimpleName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName());// 创建Function名
                    ParamsCommon.commonInsertParms(map);


                    log.info("第"+a+"次");
                    log.info("BiGenerated"+map.get("BiGenerated"));
                    Integer cout = seTenantBillMapper.addTenantBill(map);
                    if (cout<=0){
                        result.putFailed("新增宽带费账单失败");
                    }else{
                        coutNet++;
                    }

                }
                if (coutNet==paCount){
                    result.putSuccess("新增宽带费账单成功");
                }else{
                    result.putFailed("新增宽带费账单失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//事务回滚
        } finally {
            lock.unlock();
        }
        return result;
    }

}
